package test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import dsa.LinkedList;
import dsa.ListIterator;

public class MattPetroTest {
	LinkedList names;
	ListIterator namesIt;

	@Before
	public void setUp() throws Exception {
		names = new LinkedList();
		names.addLast("Mike");
		names.addLast("Jeff");
		names.addLast("Dom");
		names.addLast("Kelly");
		names.addLast("Brittany");
		names.addLast("Ray");
		
		namesIt = names.listIterator(0);
	}

	@After
	public void tearDown() throws Exception {
	}
	
	/**
	 * Tests the get method
	 */
	@Test
	public void getTest() {
		assertTrue(names.get(2).equals("Dom"));
		assertTrue(names.get(4).equals("Brittany"));
		assertTrue(names.get(0).equals("Mike"));
		assertTrue(names.get(5).equals("Ray"));
	}
	
	/**
	 * Tests the indexOf method
	 */
	@Test
	public void indexOfTest() {
		assertTrue(names.indexOf("Kelly") == 3);
		assertTrue(names.indexOf("Mike") == 0);
		assertTrue(names.indexOf("Ray") == 5);
		assertTrue(names.indexOf("Jake") == -1);
	}
	
	/**
	 * Tests the contains method
	 */
	@Test
	public void containsTest() {
		assertTrue(names.contains("Dom")== true);
		assertTrue(names.contains("Kelly")== true);
		assertTrue(names.contains("Jeff")== true);
		assertTrue(names.contains("Jake")== false);
	}
	
	/**
	 * Tests the size method
	 */
	@Test
	public void sizeTest() {
		assertTrue(names.size() == 6);
		names.addLast("Jake");
		assertTrue(names.size() == 7);
		
	}
	
	/**
	 * Tests the getFirst method
	 */
	@Test 
	public void getFirstTest() {
		assertTrue(names.getFirst().equals("Mike"));
	}
	
	/**
	 * Tests the getLast method
	 */
	@Test
	public void getLastTest() {
		assertTrue(names.getLast().equals("Ray"));
	}
	
	/**
	 * Tests the remove method
	 */
	@Test
	public void removeTest() {
		assertTrue(names.remove(1).equals("Jeff"));
		assertTrue(!(names.get(1).equals("Jeff")));
	}
	
	/**
	 * Tests the set method
	 */
	@Test
	public void setTest() {
		assertTrue(names.set(2, "Jess").equals("Dom"));
		assertTrue(names.get(2).equals("Jess"));
	}
	
	/**
	 * Tests the toArray method
	 */
	@Test
	public void toArrayTest() {
		Object[] testArray = new Object[names.size()];
		Object[] cloneArray = new Object[names.size()];
		
		for (int i = 0; i < testArray.length; i++)
			testArray[i] = names.get(i);
		
		cloneArray = names.toArray();
		
		for (int i = 0; i < cloneArray.length; i++)
			assertTrue(cloneArray[i].equals(testArray[i]));
	}
	
	/**
	 * Tests the lastIndexOf method
	 */
	/*
	@Test
	public void lastIndexOfTest() {
		names.addLast("Mike");
		assertTrue(names.lastIndexOf("Mike") == 6);
	}
	*/
	
	/**
	 * Tests the clone method
	 */
	@Test
	public void cloneTest() {
		LinkedList cloneList =(LinkedList) names.clone();
		
		for (int i = 0; i < names.size(); i++)
			assertTrue(cloneList.get(i).equals(names.get(i)));
	}
	
	@Test
	public void nextTest() {
		assertEquals(namesIt.next(), "Mike");
		assertEquals(namesIt.next(), "Jeff");
		assertEquals(namesIt.next(), "Dom");
		assertEquals(namesIt.next(), "Kelly");
		assertEquals(namesIt.next(), "Brittany");
		assertEquals(namesIt.next(), "Ray");
	}
	
	@Test
	public void hasNextTest() {
		for (int i = 0; i < 6; i++) {
			assertTrue(namesIt.hasNext());
			namesIt.next();
		}
		
		assertFalse(namesIt.hasNext());
	}
	
	@Test
	public void previousTest() {
		for (int i = 0; i < 6; i++) {
			namesIt.next();
		}
		
		assertEquals(namesIt.previous(), "Brittany");
		assertEquals(namesIt.previous(), "Kelly");
		assertEquals(namesIt.previous(), "Dom");
		assertEquals(namesIt.previous(), "Jeff");
		assertEquals(namesIt.previous(), "Mike");
	}
	
	@Test
	public void hasPreviousTest() {
		assertFalse(namesIt.hasPrevious());
		namesIt.next();
		assertFalse(namesIt.hasPrevious());
		
		for (int i = 0; i < 6; i++)
			namesIt.next();
		
		for (int i = 0; i < 5; i++) {
			assertTrue(namesIt.hasPrevious());
			namesIt.previous();
		}
	}
	
	@Test
	public void nextIndexTest() {
		for (int i = 1; i<=6; i++) {
			assertEquals(namesIt.nextIndex(), i);
			namesIt.next();
		}
		
		assertEquals(namesIt.nextIndex(), 6);
	}
	
	@Test
	public void previousIndexTest() {
		assertEquals(namesIt.previousIndex(), -1);
		
		for (int i = 0; i < 6; i++)
			namesIt.next();
		
		for (int i = 5; i >=1; i--) {
			assertEquals(namesIt.previousIndex(), i);
			namesIt.previous();
		}
	}
	
	@Test
	public void removeTestIt() {
		namesIt.next();
		namesIt.remove();
		assertEquals(namesIt.next(), "Jeff");
		namesIt.remove();
		assertEquals(namesIt.next(), "Dom");
		
		for (int i = 0; i < 3; i++)
			namesIt.next();
		
		namesIt.remove();
		assertEquals(namesIt.previous(), "Brittany");
		namesIt.remove();
		namesIt.remove();
		assertEquals(namesIt.previous(), "Kelly");
	}
	
	@Test
	public void setTestIt() {
		namesIt.next();
		namesIt.set("John");
		namesIt.next();
		
		assertEquals(namesIt.previous(), "John");
	}
}
